package com.teamnet.app;

/**
 * Created with IntelliJ IDEA.
 * User: Georgiana.Scarlat
 * Date: 6/20/12
 * Time: 4:16 PM
 * To change this template use File | Settings | File Templates.
 */

import java.lang.annotation.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Tasty {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@interface FoodType {
    String madeBy() default "somebody";

    int expiresIn() default 0;
}

@Target(ElementType.METHOD)
@Inherited
@interface Review {
}


@FoodType(madeBy = "Me", expiresIn = 5)
public class Food {


    public int makeDefault() {
        int food = 0;
        Class clasa = null;
        try {
            clasa = Class.forName(this.getClass().getName());
            Field fields[] = clasa.getDeclaredFields();

            for (Field field : fields) {

                field.setAccessible(true);

                food += (Integer) field.get(this);


            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            return food;
        }

    }

    public int makeDeLuxe() {

        int food = 0;
        Class clasa = null;
        try {
            clasa = Class.forName(this.getClass().getName());
            Field fields[] = clasa.getDeclaredFields();

            for (int i = 0; i < fields.length; i++) {

                if (fields[i].isAnnotationPresent(Tasty.class)) {

                    fields[i].setAccessible(true);
                    food += (Integer) fields[i].get(this);

                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            return food;
        }


    }

    @Review
    public String reviewRemark() {

        return "Pretty Good";
    }

    @Review
    public int reviewGrade() {

        return 6;
    }

}

class Salad extends Food {

    @Tasty
    int tomatoes;
    int onions;
    int carrots;
    @Tasty
    int cucambers;
    @Tasty
    int cheese;

    public Salad() {
        this.tomatoes = 10;
        this.onions = 11;
        this.carrots = 5;
        this.cucambers = 9;
        this.cheese = 2;
    }


}

@FoodType(madeBy = "Me", expiresIn = 0)
class Pizza extends Food {

    @Tasty
    int mushrooms;
    @Tasty
    int bread;
    @Tasty
    int meat;
    int tomatoes;

    Pizza() {
        this.mushrooms = 20;
        this.bread = 1;
        this.meat = 14;
        this.tomatoes = 10;
    }

    @Override
    public String reviewRemark() {
        return "Horrible";
    }
}

class Auxiliary {
    public static void main(String[] args) {


        String what = "com.teamnet.app.Salad";

        try {
            Class clasa = Class.forName(what);


            if (clasa.isAnnotationPresent(FoodType.class)) {

                Annotation annotation = clasa.getAnnotation(FoodType.class);
                if ((Integer) annotation.annotationType().getDeclaredMethod("expiresIn").invoke(annotation) > 0) {
                    Constructor cons = clasa.getDeclaredConstructor();
                    Object object = cons.newInstance();

                    Method method = clasa.getMethod("makeDeLuxe");
					
					

					System.out.println("New feature");
                    System.out.println("Modify something branch and trunk..."+what + " DeLuxe = " + method.invoke(object));
                    Method methods[] = clasa.getMethods();
                    for (int k = 0; k < methods.length; k++) {

                        if (methods[k].isAnnotationPresent(Review.class)) {

                            Object o = methods[k].invoke(object);
                            System.out.println("Review: " + o);
                        }
                    }


                } else {

                    System.out.println("Food has expired");
                }


            } else {

                System.out.println("Can't make " + what + "because it isn't o food type");
            }
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            System.out.println("....");
        }


    }
}
